/* 
 *  <copyright file="BaseMenuScreen.cs" company="Wesley Jowitt">
 *  
 *  SobrietyEngine: Copyright (c) 2011 Wesley Jowitt
 *  
 *  This software is distributed under a software license.
 *   * As of the creation time of this file, the license in use is the Microsoft Permissive License (Ms-PL) 
 *    * The license can be viewed at:
 *     * License.Txt in the root folder of this project
 *      * http://sobrietyengine.codeplex.com/license
 *       * http://www.microsoft.com/opensource/licenses.mspx
 *       
 *  </copyright>
 *   */


using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SobrietyEngine.Events;
using SobrietyEngine.Events.Input;
using SobrietyEngine.Input;
using SobrietyEngine.PlayerData;
using SobrietyEngine.Screens;

/*
 * Ugly leftover code from initial Dream build play comp. needs updating.
 * this is hideous
 * 
 * 
 * 
 */
namespace SEGameExample.Screens
{
    /// <summary>
    /// Base class for screens that contain a menu of options. The PlayerOne can
    /// move worldUp and down to select an entry, or cancel to back out of the screen.
    /// </summary>
    abstract class BaseMenu : BaseScreen, IEventListener
    {

        PlayerInfo owner;

        protected List<List<string>> menuEntries = new List<List<string>>();
        protected int selectedEntry = 0;
        protected List<int> selectedEntryX = new List<int>();

        protected Vector2 position = Vector2.Zero;
        private float leftBorder = 100;
        //bool JoyHeld,MenuUp;
        TimeSpan LastMenuItemChange;

        //u,r,d,vertIndecies
        protected Boolean[] joyDir = new Boolean[] { false, false, false, false };
        protected float nextJoyInput = 0.0f;

        /// <summary>
        /// Gets the list of menu entry strings, so derived classes can add
        /// or change the menu contents.
        /// </summary>
        protected List<List<string>> MenuEntries
        {
            get { return menuEntries; }
        }

        public float LeftBorder
        {
            get { return leftBorder; }
            set { leftBorder = value; }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// 

        public BaseMenu(PlayerInfo _owner)
        {
            owner = _owner;
        }

        public BaseMenu()
            : base()
        {
            LastMenuItemChange = new TimeSpan(0, 0, 0, 0, 0);
//            TransitionOnTime = TimeSpan.FromSeconds(0.5);
//            TransitionOffTime = TimeSpan.FromSeconds(0.5);
        }


        public override void Show()
        {
            base.Show();
            RegisterEventListeners();
        }

        public override void Hide()
        {
            base.Hide();
            UnregisterEventListeners();
        }

        public override void RegisterEventListeners()
        {
            //add controller listener events
            if (ListenersActive)
                return;

            EventRouter.AddEventListener(typeof(JoystickMove), this);
            EventRouter.AddEventListener(typeof(ButtonPress), this);
            EventRouter.AddEventListener(typeof(ButtonRelease), this);
            EventRouter.AddEventListener(typeof(Trigger), this);

            EventRouter.AddEventListener(typeof(KeyPress), this);

            ListenersActive = true;
        }

        public override void UnregisterEventListeners()
        {
            if (!ListenersActive)
                return;
            //remove controller listener events
            EventRouter.RemoveEventListener(typeof(JoystickMove), this);
            EventRouter.RemoveEventListener(typeof(ButtonPress), this);
            EventRouter.RemoveEventListener(typeof(ButtonRelease), this);
            EventRouter.RemoveEventListener(typeof(Trigger), this);

            EventRouter.RemoveEventListener(typeof(KeyPress), this);

            ListenersActive = false;
        }

        public override void Update(GameTime gameTime, Boolean coveredByOtherScreen, IScreen otherScreen)
        {
            base.Update(gameTime, coveredByOtherScreen, otherScreen);//, coveredByOtherScreen);

            if (true)//!coveredByOtherScreen)
            {
                nextJoyInput -= gameTime.ElapsedGameTime.Milliseconds;
                if (nextJoyInput <= 0)
                {
                    nextJoyInput = 100.0f;
                    if (joyDir[0])
                    {
                        soundManager.Play("MenuMove");
                        selectedEntry--;
                        if (selectedEntry < 0)
                        {
                            selectedEntry = menuEntries.Count - 1;
                        }
                    }
                    else if (joyDir[1])
                    {
                        soundManager.Play("MenuMove");
                        selectedEntryX[selectedEntry]++;
                        if (selectedEntryX[selectedEntry] >= menuEntries[selectedEntry].Count)
                        {
                            selectedEntryX[selectedEntry] = 0;
                        }
                    }
                    else if (joyDir[2])
                    {
                        soundManager.Play("MenuMove");
                        selectedEntry++;
                        if (selectedEntry >= menuEntries.Count)
                        {
                            selectedEntry = 0;
                        }
                    }
                    else if (joyDir[3])
                    {
                        soundManager.Play("MenuMove");
                        selectedEntryX[selectedEntry]--;
                        if (selectedEntryX[selectedEntry] < 0)
                        {
                            selectedEntryX[selectedEntry] = menuEntries[selectedEntry].Count - 1;
                        }
                    }
                }
            }
        }

        public override void HandleEvent(Event e)
        {
            //in case there is an old event comming through...
            if (this.Active)
            {
                //if (!listenersActive)
                  //  return;
                if (e.Type == typeof(KeyPress))
                {
                    KeyPress kped = (KeyPress)e.Data;
                    Keys key = kped.Key;
                    if (key == Keys.Up)
                    {
                        soundManager.Play("MenuMove");
                        selectedEntry--;
                        if (selectedEntry < 0)
                            selectedEntry = menuEntries.Count - 1;
                    }
                    else if (key == Keys.Down)
                    {
                        soundManager.Play("MenuMove");
                        selectedEntry++;
                        if (selectedEntry >= menuEntries.Count)
                            selectedEntry = 0;
                    }
                    else if (key == Keys.Enter)
                    {
                        OnSelectEntry(selectedEntry);
                    }
                }

                else if (e.Type == typeof(ButtonPress))
                {
                    ButtonPress buttonEventData = (ButtonPress)e.Data;
                    GamepadEnums.GamepadButton button = buttonEventData.Button;

                    PlayerInfo playerInfo = null;
                   // if(buttonEventData.PlayerGuid!= null)
                   //     playerInfo = (PlayerInfo)buttonEventData.PlayerGuid.Resolve();

                    if (owner == null || owner == playerInfo)
                    {
                        if (button == GamepadEnums.GamepadButton.Start)
                        {
                            OnSelectEntry(selectedEntry);
                        }
                        else if (button == GamepadEnums.GamepadButton.A)
                        {
                            OnSelectEntry(selectedEntry);
                        }
                        else if (button == GamepadEnums.GamepadButton.B)
                        {
                            OnCancel();
                        }
                        else if (button == GamepadEnums.GamepadButton.DU)
                        {
                            soundManager.Play("MenuMove");
                            selectedEntry--;
                            if (selectedEntry < 0)
                                selectedEntry = menuEntries.Count - 1;
                        }
                        else if (button == GamepadEnums.GamepadButton.DR)
                        {
                            soundManager.Play("MenuMove");
                            selectedEntryX[selectedEntry]++;
                            if (selectedEntryX[selectedEntry] >= menuEntries[selectedEntry].Count)
                                selectedEntryX[selectedEntry] = 0;
                        }
                        else if (button == GamepadEnums.GamepadButton.DL)
                        {
                            soundManager.Play("MenuMove");
                            selectedEntryX[selectedEntry]--;
                            if (selectedEntryX[selectedEntry] < 0)
                                selectedEntryX[selectedEntry] = menuEntries[selectedEntry].Count - 1;
                        }
                        else if (button == GamepadEnums.GamepadButton.DD)
                        {
                            soundManager.Play("MenuMove");
                            selectedEntry++;
                            if (selectedEntry >= menuEntries.Count)
                                selectedEntry = 0;
                        }
                    }
                }
                else if (e.Type == typeof(JoystickMove))
                {
                    JoystickMove jed = (JoystickMove)e.Data;
                    PlayerInfo playerInfo = null;
                    //if(jed.PlayerGuid != null)
                     //   playerInfo = (PlayerInfo)jed.PlayerGuid.Resolve();

                    if (owner == null || owner == playerInfo)
                    {
                        if (((JoystickMove)e.Data).Y < -0.5)
                        {
                            joyDir[2] = true;
                        }
                        else
                            joyDir[2] = false;

                        if (((JoystickMove)e.Data).Y > 0.5)
                        {
                            joyDir[0] = true;
                        }
                        else
                            joyDir[0] = false;

                        if (((JoystickMove)e.Data).X > 0.5)
                        {
                            joyDir[1] = true;
                        }
                        else
                            joyDir[1] = false;

                        if (((JoystickMove)e.Data).X < -0.5)
                        {
                            joyDir[3] = true;
                        }
                        else
                            joyDir[3] = false;
                    }
                }
            }
        }


        /// <summary>
        /// Notifies derived classes that a menu entry has been chosen.
        /// </summary>
        protected abstract void OnSelectEntry(int entryIndex);


        /// <summary>
        /// Notifies derived classes that the menu has been cancelled.
        /// </summary>
        protected abstract void OnCancel();

        public override void Initialize()
        {
            base.Initialize();
            MenuSpriteFont = ScreenManager.AssetGameService.Load<SpriteFont>("Fonts/menuFont");
            CalculatePosition();

        }

        protected virtual void CalculatePosition()
        {
            float totalHeight;
            totalHeight = MenuSpriteFont.MeasureString("T").Y + MenuSpriteFont.LineSpacing;
            totalHeight *= menuEntries.Count;

            position.Y = (ScreenManager.GraphicsDevice.Viewport.Height - totalHeight) / 2 - 20;
            position.X = (ScreenManager.GraphicsDevice.Viewport.Width) / 2;
        }

        /// <summary>
        /// Draws the menu.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {

            //ScreenManager.GraphicsDevice.Clear(Color.Black)


            Vector2 itemPosition = position;

            // Draw each menu entry in turn.

            for (int i = 0; i < menuEntries.Count; i++)
            {
                Color color;
                float scale;
                float scale2 = 1.0f;
                Color color2 = Color.Green;

                if (Active && (i == selectedEntry))
                {
                    //// The selected entry is yellow, and has an animating size.
                    double time = gameTime.TotalGameTime.TotalSeconds;

                    float pulsate = (float)Math.Sin(time * 3) + 1;
                    scale2 = 1 + ((float)Math.Cos(time * 3) + 1) * 0.05f;
                    scale = 1 + pulsate * 0.05f;

                    color = Color.MidnightBlue;
                    color2 = Color.White;


                }
                else
                {
                    // Other entries are green.
                    color = Color.Green;
                    scale = 1;
                }

                // Modify the alpha to fade text out during transitions.
                color = new Color(color.R, color.G, color.B);//, TransitionAlpha);

                // Draw text, centered on the middle of each line.
                Vector2 origin = new Vector2(0, ScreenManager.MenuSpriteFont.LineSpacing / 2);
                itemPosition.X = position.X - (MenuSpriteFont.MeasureString(menuEntries[i][selectedEntryX[i]]).X / 2);
                ScreenManager.SpriteBatch.DrawString(MenuSpriteFont, menuEntries[i][selectedEntryX[i]],
                                                     itemPosition, color, 0, origin, scale,
                                                     SpriteEffects.None, 0);

                if (Active && (i == selectedEntry))
                {
                    ScreenManager.SpriteBatch.DrawString(MenuSpriteFont, menuEntries[i][selectedEntryX[i]],
                                                         new Vector2(itemPosition.X - 7, itemPosition.Y), color2, 0, origin, scale2,
                                                         SpriteEffects.None, 0.01f);
                }
                itemPosition.Y += MenuSpriteFont.LineSpacing;
            }
        }
    }
}
